﻿using OpenCvSharp;
using SearchForPicturesWithPictures.Common;
using SearchForPicturesWithPictures.View;
using SearchForPicturesWithPictures.View.ViewEx;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;

namespace SearchForPicturesWithPictures
{
    public unsafe partial class FrmMain : Form
    {
        private BindingList<ImageInfo> _imageInfo = new BindingList<ImageInfo>();
        public FrmMain()
        {
            InitializeComponent();

            //waitingControl1.Visible = false;
            waitingControl1.Activate = false;
            dgvInfo.AutoGenerateColumns = false;
            dgvInfo.DataSource = _imageInfo;
        }
        private string _targetPath;
        /// <summary>
        /// 选择目标图像
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pbTarget_Click(object sender, EventArgs e)
        {
            using OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Image files (*.jpg; *.jpeg; *.png)|*.jpg; *.jpeg; *.png";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                LoadImage(openFileDialog.FileName, this.pbTarget);
                _targetPath = openFileDialog.FileName;
            }
        }
        private void LoadImage(string path, PictureBox pictureBox)
        {
            if (File.Exists(path))
            {
                LoadImage(new Bitmap(path), pictureBox);
            }
        }
        private void LoadImage(Image image, PictureBox pictureBox)
        {
            if (pictureBox.Image != null)
                pictureBox.Image.Dispose();
            pictureBox.Image = image;
        }
        private bool _isRun = false;
        readonly string[] imageExtensions = { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff" };
        private void btnSearch_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(_targetPath))
            {
                MessageBox.Show("请选择图像");
                return;
            }
            if (_isRun)
            {
                MessageBox.Show("正在搜索中");
                return;
            }
            var rootPath = txtRootPath.Text;
            if (string.IsNullOrEmpty(rootPath))
            {
                MessageBox.Show("请选择搜索路径");
                return;
            }
            if (!Directory.Exists(rootPath))
            {
                MessageBox.Show("搜索路径不存在");
                return;
            }
            if (pbSub.Image != null)
                pbSub.Image.Dispose();
            pbSub.Image = null;
            _lastRowIndex = -1;
            lblCount.Text = $"搜索文件总数：{0}";
            lblMessage.Text = "正在搜索...";
            rtxtMsg.Text = "";
            AddMsg("正在搜索...");
            _isRun = true;
            _stop = false;
            _imageInfo.Clear();
            //waitingControl1.Visible = true;
            waitingControl1.Activate = true;
            Task.Factory.StartNew(() =>
            {
                var imageFiles = FindImageFiles(rootPath, imageExtensions);
                lblCount.ExecBeginInvoke(() =>
                {
                    lblCount.Text = $"搜索文件总数：{imageFiles.Length}";
                });
                AddMsg($"搜索文件总数：{imageFiles.Length}");
                int index = 0;
                int curIndex = 1;
                double max = (double)numericUpDown1.Value;
                using SurfHelper surfHelper = new SurfHelper(max);
                surfHelper.SerImageSrc(_targetPath);
                var list = imageFiles.AsParallel().Select(file =>
                 {
                     AddMsg($"当前进度：{curIndex}，剩余：{imageFiles.Length - curIndex}");
                     curIndex++;
                     if (!_stop && file != _targetPath)
                     {
                         using var d = surfHelper.MatchPicBySurf(file, out var similarityScore);
                         if (similarityScore > 0)
                         {
                             var emtity = new ImageInfo
                             {
                                 FilePath = file,
                                 SimilarityScore = similarityScore,
                                 Index = ++index,
                             };
                             this.ExecBeginInvoke(() =>
                             {
                                 _imageInfo.Add(emtity);
                             });
                             return emtity;
                         }
                     }
                     return null;
                 }).Where(t => t != null).OrderByDescending(t => t.SimilarityScore).ToList();

                this.ExecBeginInvoke(() =>
                {
                    _imageInfo.Clear();
                    index = 0;
                    foreach (var item in list)
                    {
                        item.Index = ++index;
                        _imageInfo.Add(item);
                    }
                });

                _isRun = false;
                lblMessage.ExecBeginInvoke(() =>
                {
                    lblMessage.Text = "搜索完成...";
                    //waitingControl1.Visible = false;
                    waitingControl1.Activate = false;
                });
                AddMsg("搜索完成...");
            });
        }
        private void AddMsg(string msg)
        {
            rtxtMsg.ExecBeginInvoke(() =>
            {
                rtxtMsg.AppendText(msg + "\r\n");
            });
        }
        string[] FindImageFiles(string rootPath, string[] extensions)
        {
            try
            {
                // 获取C盘下所有图片文件的路径
                var imageFiles = Directory.EnumerateFiles(rootPath, "*.*", SearchOption.AllDirectories)
                                      .Where(file => imageExtensions.Contains(Path.GetExtension(file)))
                    .ToArray();

                return imageFiles;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"An error occurred: {ex.Message}");
            }
            return new string[0];
        }
        private bool _stop = false;
        private void btnStop_Click(object sender, EventArgs e)
        {
            _stop = true;
        }
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            _stop = true;
            _isRun = false;
            _imageInfo.Clear();
            this.Dispose();
            Application.ExitThread();
            Application.Exit();
            Process.GetCurrentProcess().Kill();
        }
        int _lastRowIndex = -1;
        private void dgvInfo_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (_imageInfo.Count == 0 || e.RowIndex == -1 || _lastRowIndex == e.RowIndex) return;
            if (e.RowIndex >= _imageInfo.Count) return;
            _lastRowIndex = e.RowIndex;
            var info = _imageInfo[e.RowIndex];
            LoadImage(info.FilePath, pbSub);
        }

        private void btnLoadRootPath_Click(object sender, EventArgs e)
        {
            using FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            folderBrowserDialog.Description = "请选择搜索路径";
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                txtRootPath.Text = folderBrowserDialog.SelectedPath;
            }
        }

        private void rtxtMsg_TextChanged(object sender, EventArgs e)
        {
            rtxtMsg.SelectionStart = rtxtMsg.Text.Length;
            rtxtMsg.ScrollToCaret();
        }
    }
    public class ImageInfo
    {
        public string FilePath { get; set; }
        public float SimilarityScore { get; set; }
        public int Index { get; set; }
    }
}
